﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.IO;
using System.Collections.ObjectModel;
using OfficeOpenXml;
using Common.Utility;

namespace Common.ControlDevice
{
    public enum ErrorLevelCategory
    {
        Error,                // 错误
        Warning,              // 警告
        Message,              // 消息
        Info                  // 用于数据检查时输出检查正确的日志
    }

    //2020.11.25 wj 改：相关窗口中的错误列表，都可以绑定该类，如有需要可以添加，使用时只使用对应的信息即可。由于列表会随窗口关闭而析构，不用担心内存
    public class ErrorInfo : INotifyPropertyChanged
    {
        public ErrorInfo()
        { }

        public ErrorInfo(string detail)
		{
            this.ErrorLevel = ErrorLevelCategory.Info;
            this.Detail = detail;
		}

        public ErrorInfo(ErrorLevelCategory errorLevel, String detail)
        {
            this.ErrorLevel = errorLevel;
            this.Detail = detail;
        }

        public ErrorInfo(uint sequence, ErrorLevelCategory errorLevel, String detail)
        {
            this.Sequence = sequence;
            this.ErrorLevel = errorLevel;
            this.Detail = detail;
        }

        public ErrorInfo(ErrorLevelCategory errorLevel, String type, String detail)
        {
            this.Type = type;
            this.ErrorLevel = errorLevel;
            this.Detail = detail;
        }

        public ErrorInfo(uint sequence, ErrorLevelCategory errorLevel, String type, String deviceName, String detail, string routeSequence = "")
        {
            this.Sequence = sequence;
            this.ErrorLevel = errorLevel;
            this.Type = type;
            this.DeviceName = deviceName;
            this.Detail = detail;
            this.RouteSequence = routeSequence;
        }

        /**
         * \brief 根据错误等级，转换为对应的字符串
         * \param[in] realValue 错误的等级
         * \retval void 空
         */
        public static string ErrorLevelToString(ErrorLevelCategory realValue)//2018.09.05 he 增：
        {
            string ret = String.Empty;
            switch (realValue)
            {
                case ErrorLevelCategory.Info:
                    ret = "通过";
                    break;
                case ErrorLevelCategory.Error:
                    ret = "错误";
                    break;
                case ErrorLevelCategory.Warning:
                    ret = "警告";
                    break;
                case ErrorLevelCategory.Message:
                    ret = "消息";
                    break;
                default:
                    break;
            }
            return ret;
        }

        //信息类别 主要用于信息打印
        private uint infomationKind = 0;
        public uint InfomationKind
        {
            get { return infomationKind; }
            set
            {
                infomationKind = value;
                OnNotifyPropertyChanged("InfomationKind");
            }
        }

        //错误生成的序号
        private uint sequence = 0;
        public uint Sequence
        {
            get { return sequence; }
            set
            {
                sequence = value;
                OnNotifyPropertyChanged("Sequence");
            }
        }
        //错误的级别
        private ErrorLevelCategory errorLevel = ErrorLevelCategory.Error;
        public ErrorLevelCategory ErrorLevel
        {
            get { return errorLevel; }
            set
            {
                errorLevel = value;
                OnNotifyPropertyChanged("ErrorLevel");
            }
        }

        //包含错误的类型，如某个标签页或某个类型的数据
        private string type = String.Empty;
        public string Type
        {
            get { return type; }
            set
            {
                type = value;
                OnNotifyPropertyChanged("Type");
            }
        }
        //包含错误的设备名
        private string deviceName = String.Empty;
        public string DeviceName
        {
            get { return deviceName; }
            set
            {
                deviceName = value;
                OnNotifyPropertyChanged("DeviceName");
            }
        }
        //具体的错误数据
        private string detail = String.Empty;
        public string Detail
        {
            get { return detail; }
            set
            {
                detail = value;
                OnNotifyPropertyChanged("Detail");
            }
        }

        //进路的序号，编辑进路窗口中以该值标识包含错误的进路
        private string routeSequence = String.Empty;
        public string RouteSequence
        {
            get { return routeSequence; }
            set
            {
                routeSequence = value;
                OnNotifyPropertyChanged("RouteSequence");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnNotifyPropertyChanged(string propertyName)
        {
            if (null != PropertyChanged)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    public class LogDataManager
    {
        //更新进度条
        public static Action<int> UpdateProgress = null;

        /**
         * \brief 导出日志到log数据响应函数
         *
         * \param [in] fileName 文件路径
         * \param [in] ResultCollection 提示信息结果集
         * \param [ref] index  序号
         * \retval void
         */
        public static void ExportToLog(string fileName, ObservableCollection<ErrorInfo> ResultCollection, ref uint index)
        {
            try
            {
                FileStream stream = new FileStream(fileName, FileMode.Create);
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    foreach (var v in ResultCollection.Where(x => { return ErrorLevelCategory.Info != x.ErrorLevel; }))
                    {
                        writer.WriteLine("{0}\t{1}\t{2}\t{3}", v.Sequence, v.Type.PadRight(10), v.DeviceName, v.Detail);
                    }
                    writer.Close();
                }
                stream.Close();
                ResultCollection.Clear();
                index = 1;
                ResultCollection.Add(new ErrorInfo()
                {
                    Sequence = index++,
                    ErrorLevel = ErrorLevelCategory.Info,
                    Type = "结果导出",
                    DeviceName = string.Empty,
                    Detail = "数据导入/出结果已保存至目录：" + fileName
                });
            }
            catch (Exception ex)
            {
                ResultCollection.Add(new ErrorInfo()
                {
                    Sequence = index++,
                    ErrorLevel = ErrorLevelCategory.Info,
                    Type = "结果导出",
                    DeviceName = string.Empty,
                    Detail = "数据导入/出结果异常：" + ex.ToString()
                });
            }
        }

        /**
         * \brief 导出日志到excel数据响应函数
         * 
         * \param [in] fileName 文件路径
         * \param [in] ResultCollection 提示信息结果集
         * \param [ref] index  序号
         * \retval void 空
         */
        public static void ExportToExcel(string fileName, ObservableCollection<ErrorInfo> ResultCollection, ref uint index)
        {
            bool result = true;
            try
            {
                int fileCount = 0;
                FileInfo newFile = new FileInfo(fileName);
                if (newFile.Exists)
                {
                    newFile.Delete();
                    newFile = new FileInfo(fileName);
                }
                using (ExcelPackage book = new ExcelPackage(newFile))
                {
                    ExcelWorksheet errorSheet = book.Workbook.Worksheets.Add("列控数据导入窗口提示信息");
                    errorSheet.Cells[1, 1].Value = "序号";
                    errorSheet.Cells[1, 2].Value = "类型";
                    errorSheet.Cells[1, 3].Value = "设备名";
                    errorSheet.Cells[1, 4].Value = "内容";
                    if (null != UpdateProgress)
                    {
                        UpdateProgress(fileCount++);
                    }
                    int i = 2;
                    foreach (var v in ResultCollection)
                    {
                        errorSheet.Cells[i, 1].Value = v.Sequence;
                        errorSheet.Cells[i, 2].Value = v.Type;
                        errorSheet.Cells[i, 3].Value = v.DeviceName;
                        errorSheet.Cells[i, 4].Value = v.Detail;
                        i++;
                        if (null != UpdateProgress)
                        {
                            UpdateProgress(fileCount++);
                        }
                    }
                    errorSheet.Cells.AutoFitColumns();
                    book.Save();
                }
            }
            catch (Exception ex)
            {
                result = false;
                ResultCollection.Add(new ErrorInfo() { Sequence = index++, Type = "导出结果", Detail = DCTControlConstant.GenerateExceptionInfo(ex) });
            }
            finally
            { }

            if (result)
            {
                ResultCollection.Clear();
                index = 1;
                ResultCollection.Add(new ErrorInfo()
                {
                    Sequence = index++,
                    ErrorLevel = ErrorLevelCategory.Message,
                    Type = "导出结果",
                    DeviceName = string.Empty,
                    Detail = "数据导入结果已保存至指定目录" + fileName
                });
            }
        }
    }
}
